//
//  MPHoleView.m
//  MissPaparazzi
//
//  Created by Alexey Aleshkov on 23.09.12.
//  Copyright (c) 2012 DzeTech. All rights reserved.
//


#import "MPHoleView.h"


@implementation MPHoleView

@synthesize patternImage = _patternImage;
@synthesize holeInsets = _holeInsets;
@synthesize holeRadius = _holeRadius;
@synthesize fillColor = _fillColor;

#pragma mark -
#pragma mark Common Init / Dealloc

- (void)initialization
{
	CGFloat kInset = 4;
	_holeInsets = UIEdgeInsetsMake(kInset, kInset, kInset, kInset);
	_holeRadius = kInset * 3 / 2;
}

- (void)deinitialization
{
	[_patternImage release];
	[_fillColor release];
}

#pragma mark -
#pragma mark Init / Dealloc

- (id)initWithFrame:(CGRect)frame
{
	self = [super initWithFrame:frame];
	if (!self) {
		return nil;
	}
	
	[self initialization];
	
	return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
	self = [super initWithCoder:aDecoder];
	if (!self) {
		return nil;
	}
	
	[self initialization];
	
	return self;
}

- (void)dealloc
{
	[self deinitialization];
	[super dealloc];
}

#pragma mark -
#pragma mark Overrides

- (void)drawRect:(CGRect)rect
{
	CGContextRef context = UIGraphicsGetCurrentContext();
	
	CGRect bounds = UIEdgeInsetsInsetRect(self.bounds, _holeInsets);
	CGFloat radius = _holeRadius;
	
	CGContextSaveGState(context);

	CGMutablePathRef cutoutRect = CGPathCreateMutable();
	CGPathAddRect(cutoutRect, NULL, rect);
	
	// Create the "visible" path, which will be the shape that gets the inner shadow
	// In this case it's just a rounded rect, but could be as complex as your want
	CGMutablePathRef visiblePath = CGPathCreateMutable();
	CGRect innerRect = CGRectInset(bounds, radius, radius);
	CGPathMoveToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y);
	CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x + innerRect.size.width, bounds.origin.y);
	CGPathAddArcToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, bounds.origin.y, bounds.origin.x + bounds.size.width, innerRect.origin.y, radius);
	CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x + bounds.size.width, innerRect.origin.y + innerRect.size.height);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, innerRect.origin.x + innerRect.size.width, bounds.origin.y + bounds.size.height, radius);
	CGPathAddLineToPoint(visiblePath, NULL, innerRect.origin.x, bounds.origin.y + bounds.size.height);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x, bounds.origin.y + bounds.size.height, bounds.origin.x, innerRect.origin.y + innerRect.size.height, radius);
	CGPathAddLineToPoint(visiblePath, NULL, bounds.origin.x, innerRect.origin.y);
	CGPathAddArcToPoint(visiblePath, NULL,  bounds.origin.x, bounds.origin.y, innerRect.origin.x, bounds.origin.y, radius);
	CGPathCloseSubpath(visiblePath);

	
	CGPathAddPath(cutoutRect, NULL, visiblePath);
	CGPathCloseSubpath(cutoutRect);
	CGContextAddPath(context, cutoutRect);
	CGPathRelease(cutoutRect);
	
	// clip context to current path
	CGContextEOClip(context);
	
	[_patternImage drawAsPatternInRect:rect];

	CGContextRestoreGState(context);
	

	CGContextSaveGState(context);
	// Fill this path
	if (_fillColor) {
		[_fillColor setFill];
		CGContextAddPath(context, visiblePath);
		CGContextFillPath(context);
	}
	CGContextRestoreGState(context);
	
	CGPathRelease(visiblePath);
}

- (void)setFrame:(CGRect)frame
{
	[super setFrame:frame];
	[self setNeedsDisplay];
}

#pragma mark -
#pragma mark Properties

- (void)setPatternImage:(UIImage *)patternImage
{
	id oldValue = _patternImage;
	_patternImage = [patternImage retain];
	[oldValue release];
	[self setNeedsDisplay];
}

- (void)setHoleInsets:(UIEdgeInsets)shadowInsets
{
	_holeInsets = shadowInsets;
	[self setNeedsDisplay];
}

- (void)setHoleRadius:(CGFloat)shadowRadius
{
	_holeRadius = MAX(0, shadowRadius);
	[self setNeedsDisplay];
}

- (void)setFillColor:(UIColor *)fillColor
{
	id oldValue = _fillColor;
	_fillColor = [fillColor retain];
	[oldValue release];
	[self setNeedsDisplay];
}

@end
